/**
Prolog Music Composer V.1 (Whole Notes)
1. Chorus, Solo (based on I-IV-V-I)
Counter=5
?- chorussoloprogression('F','G').
[[F, G], [F, A#, C, D, G]]
Yes
?- chorussoloprogression('E','G').
[[E, A, D, G]]
Yes
?- chorussoloprogression('G','C').
[[G, C]]
Yes
**/
chorussoloprogression(Name1, Name2) :-
note(Note1, Name1),
note(Note2, Name2),
chorussoloprogression1(Note1, Note2, 0, _, [Note1], Progression1), notestonames(Progression1,Progression2), writeln(Progression2).
chorussoloprogression1(_, _, _, Counter, b, Progression, Progression) :-
Counter = 8, !.
chorussoloprogression1(Note, Note, _, _Counter, a, Progression, Progression) :- !.
chorussoloprogression1(Note1, Note2, Counter1, Flag1, Progression1, Progression2) :-
Counter2 is Counter1 + 1,
step1(Note1, Note3),
append(Progression1, [Note3], Progression3),
chorussoloprogression2(Note3, Note2, Note1, Counter2, Flag2, Progression3, Progression4),
step2(Note1, Note4),
append(Progression1, [Note4], Progression5),
chorussoloprogression2(Note4, Note2, Note1, Counter2, Flag3, Progression5, Progression6),
flag1([[Flag2, Progression4], [Flag3, Progression6]], Flag1, Progression2).
chorussoloprogression2(_, _, _, Counter, b, Progression, Progression) :-
Counter = 8, !.
chorussoloprogression2(Note, _, Note, _, _, _, _) :- !.
chorussoloprogression2(Note, Note, _, _Counter, a, Progression, Progression) :- !.
chorussoloprogression2(Note1, Note2, Note3, Counter1, Flag1, Progression1, Progression2) :-
Counter2 is Counter1 + 1,
step1(Note1, Note4),
append(Progression1, [Note4], Progression3),
chorussoloprogression2(Note4, Note2, Note3, Counter2, Flag2, Progression3, Progression4),
step2(Note1, Note5),
append(Progression1, [Note5], Progression5),
chorussoloprogression2(Note5, Note2, Note3, Counter2, Flag3, Progression5, Progression6),
flag1([[Flag2, Progression4], [Flag3, Progression6]], Flag1, Progression2).
step1(Note1, Note2) :-
Value is Note1+1, Note2 is Value mod 7. %% IV-V
step2(Note1, Note2) :-
Value is Note1+3, Note2 is Value mod 7. %% I-IV, V-I
notestonames(Progression1, Progression2) :-
clean(Progression1, Progression2).
flag1(Items, Flag, Progression) :-
flag2(Items, Flag, [], Progression), !.
flag1([], b, []) :- !.
flag2([], a, Progression, Progression) :- !.
flag2([[a,Progression1]|Items], _, Progression2, Progression3) :-
append(Progression2, [Progression1], Progression4),
flag2(Items, _, Progression4, Progression3).
flag2([[b,_]|Items], _, Progression2, Progression3) :-
flag2(Items, _, Progression2, Progression3).
clean(Items1, Items2) :-
clean1(Items1,[],Items2).
clean1([],I,I).
clean1(Items,I1,F1) :-
allnumbers(Items,[],Names),append(I1,[Names],F1),!.
clean1([Item|Items],I1,F1) :-
clean1(Item, I1, F2),
clean1(Items, F2, F1).
allnumbers([],Names,Names).
allnumbers([Item|Items],Names1,Names2):-
number(Item),note(Item,Name),append(Names1,[Name],Names3),allnumbers(Items,Names3,Names2).
note(0,'C').
note(1,'D').
note(2,'E').
note(3,'F').
note(4,'G').
note(5,'A').
note(6,'B').

/**
Prolog Music Composer V.1 (Whole Notes)
2. Verse (based on I-ii-vii°-I)
Counter=4
?- verseprogression('C','D').
[[C, D], [C, C#, D]]
Yes
?- verseprogression('C','C#').
[[C, D, E, C#], [C, D, B, C#], [C, A, B, C#], [C, C#]]
Yes
?- verseprogression('C','D').
[[C, D], [C, C#, D]]
Yes
?- verseprogression('C','D#').
[[C, D, D#], [C, A, F#, D#], [C, C#, D#], [C, C#, D, D#]]
Yes
**/
verseprogression(Name1, Name2) :-
note(Note1, Name1),
note(Note2, Name2),
verseprogression1(Note1, Note2, 0, _, [Note1], Progression1), notestonames(Progression1,Progression2),writeln(Progression2).
verseprogression1(_, _, Counter, b, Progression, Progression) :-
Counter = 4, !.
verseprogression1(Note, Note, _Counter, a, Progression, Progression) :- !.
verseprogression1(Note1, Note2, Counter1, Flag1, Progression1, Progression2) :-
Counter2 is Counter1 + 1,
step1(Note1, Note3),
append(Progression1, [Note3], Progression3),
verseprogression2(Note3, Note2, Note1, Counter2, Flag2, Progression3, Progression4),
step2(Note1, Note4),
append(Progression1, [Note4], Progression5),
verseprogression2(Note4, Note2, Note1, Counter2, Flag3, Progression5, Progression6),
step3(Note1, Note5),
append(Progression1, [Note5], Progression7),
verseprogression2(Note5, Note2, Note1, Counter2, Flag4, Progression7, Progression8),
flag1([[Flag2, Progression4], [Flag3, Progression6], [Flag4, Progression8]], Flag1, Progression2).
verseprogression2(_, _, _, Counter, b, Progression, Progression) :-
Counter = 4, !.
verseprogression2(Note, _, Note, _, _, _, _) :- !.
verseprogression2(Note, Note, _, _Counter, a, Progression, Progression) :- !.
verseprogression2(Note1, Note2, Note3, Counter1, Flag1, Progression1, Progression2) :-
Counter2 is Counter1 + 1,
step1(Note1, Note4),
append(Progression1, [Note4], Progression3),
verseprogression2(Note4, Note2, Note3, Counter2, Flag2, Progression3, Progression4),
step2(Note1, Note5),
append(Progression1, [Note5], Progression5),
verseprogression2(Note5, Note2, Note3, Counter2, Flag3, Progression5, Progression6),
step3(Note1, Note6),
append(Progression1, [Note6], Progression7),
verseprogression2(Note6, Note2, Note3, Counter2, Flag4, Progression7, Progression8),
flag1([[Flag2, Progression4], [Flag3, Progression6], [Flag4, Progression8]], Flag1, Progression2).
step1(Note1, Note2) :-
Value is Note1+1, Note2 is Value mod 7. %% I-ii
step2(Note1, Note2) :-
Value is Note1+5, Note2 is Value mod 7. %% ii-vii°
step3(Note1, Note2) :-
Value is Note1+1, Note2 is Value mod 7. %% vii°-I
notestonames(Progression1, Progression2) :-
clean(Progression1, Progression2).
flag1(Items, Flag, Progression) :-
flag2(Items, Flag, [], Progression), !.
flag1([], b, []) :- !.
flag2([], a, Progression, Progression) :- !.
flag2([[a,Progression1]|Items], _, Progression2, Progression3) :-
append(Progression2, [Progression1], Progression4),
flag2(Items, _, Progression4, Progression3).
flag2([[b,_]|Items], _, Progression2, Progression3) :-
flag2(Items, _, Progression2, Progression3).
clean(Items1, Items2) :-
clean1(Items1,[],Items2).
clean1([],I,I).
clean1(Items,I1,F1) :-
allnumbers(Items,[],Names),append(I1,[Names],F1),!.
clean1([Item|Items],I1,F1) :-
clean1(Item, I1, F2),
clean1(Items, F2, F1).
allnumbers([],Names,Names).
allnumbers([Item|Items],Names1,Names2):-
number(Item),note(Item,Name),append(Names1,[Name],Names3),allnumbers(Items,Names3,Names2).
note(0,'C').
note(1,'D').
note(2,'E').
note(3,'F').
note(4,'G').
note(5,'A').
note(6,'B').